<?php

declare(strict_types=1);

namespace App\Controller\Api\V2\Goods;

use App\Controller\Api\V2\Controllers;
use App\Exception\InternalException;
use App\Exception\InvalidRequestException;
use App\Services\Goods\Good as GoodServices;
use App\Request\Goods\Good as GoodRequest;
use App\Utils\Other\Erp\Goods\Push;
use Hyperf\Collection\Arr;
use Hyperf\DbConnection\Db;
use Hyperf\Stringable\Str;
use Psr\Http\Message\ResponseInterface;
use function Hyperf\Coroutine\defer;

/**
 * 商品控制器
 * @author zx
 * @package App\Controller\Api\V2\Goods
 */
class Good extends Controllers
{
    /**
     * 请求类
     * @var string
     */
    protected string $requestClass = GoodRequest::class;

    public function __construct(GoodServices $goodServices)
    {
        parent::__construct();
        $this->services = $goodServices;
    }

    /**
     * 商品推送
     * @param Push $push
     * @return ResponseInterface
     */
    public function save(Push $push):ResponseInterface
    {
        $input = $this->input([
            'products'
        ]);
        $items = Db::transaction(function () use ($input, $push) {
            $items = [];
            $models = $this->services
                ->whereIn('product_id', array_unique(array_column($input['products'], 'item_id')))
                ->get();
            foreach ($input['products'] as $product) {
                $keys = array_keys($product);
                foreach ($keys as &$value) {
                    $value = Str::camel($value);
                }
                $product = array_combine($keys, $product);
                $product['itemID'] = $product['itemId'];
                $product['itemURL'] = '';
                $product['imageURL'] = isset($product['imageUrl'])?urldecode($product['imageUrl']):null;
                unset($product['itemId'], $product['itemUrl'], $product['imageUrl']);
                $product['shopNick'] = getShop('name');
                $product['modifyTime'] = time() * 1000;
                $product['createTime'] = time() * 1000;
                $product['status'] = 1;
                $product['skus'] = [];
                $items[] = $product;

                $key = $models->pluck('product_id')->search($product['itemID']);
                $data = [
                    'product_id' => $product['itemID'],
                    'no' => $product['itemCode'],
                    'name' => $product['title'],
                    'title' => $product['title'],
                    'price' => $product['price'],
                    'image' => $product['imageURL'],
                    'status' => 1,
                    'audit_status' => 2
                ];
                if (is_int($key)) {
                    $model = $models->get($key);
                    $model->fill($data)->save();
                } else {
                    $model = $this->services->create($data);
                    $models->push($model);
                }
            }

            return $push->handle(['items' => json_encode($items)]);
        });

        return success(compact('items'));
    }

    /**
     * 新增
     * @return ResponseInterface
     */
//    public function save():ResponseInterface
//    {
//        $input = $this->input([
//            'products'
//        ]);
//
//        Db::transaction(function () use ($input) {
//            foreach ($input['products'] as $product) {
//                /** @var \App\Model\Goods\Good $model */
//                $model = $this->services->with(['images'])->where('product_id', $product['product_id'])->first();
//                if (!$model) {
//                    /** @var \App\Model\Goods\Good $model */
//                    $model = $this->services->create($product);
//                    if (!$model->exists) {
//                        throw new InvalidRequestException();
//                    }
//                    if (!Arr::get($product, 'images')) {
//                        $product['images'][] = $model->image;
//                    }
//                    $model->images()->createMany(array_map(function ($v) {
//                        return ['image' => $v];
//                    }, $product['images']));
//                } else {
//                    if (!$model->fill($product)->save()) {
//                        throw new InternalException();
//                    }
//                    $model->images()->delete();
//                    if (!Arr::get($product, 'images')) {
//                        $product['images'][] = $model->image;
//                    }
//                    $model->images()->createMany(array_map(function ($v) {
//                        return ['image' => $v];
//                    }, $product['images']));
//                }
//            }
//        });
//
//        return stored();
//    }

    /**
     * 详情
     * @return ResponseInterface
     * @throws \Throwable
     */
    public function read():ResponseInterface
    {
        $input = $this->input(['product_id']);

        $model = $this->services
            ->with(['images'])
            ->where('product_id', $input['product_id'])
            ->firstOrFail()
            ->makeHidden([
                'id',
                'shop_id',
                'sort',
                'created_at',
                'updated_at',
                'deleted_at',
                'spec_type',
                'virtual_sales_num',
                'sales_num',
                'upc',
                'audit_status',
                'violation_reason'
            ]);

        return success($model);
    }

    /**
     * 编辑
     * @return ResponseInterface
     */
    public function status():ResponseInterface
    {
        $input = $this->input(['product_ids', 'status']);

        $this->services->whereIn('product_id', $input['product_ids'])->update(['status'=>$input['status']]);

        return updated();
    }

    /**
     * 批量删除
     * @return ResponseInterface
     * @throws \Exception
     */
    public function destroy():ResponseInterface
    {
        $input = $this->input(['product_ids']);

        $this->services->whereIn('product_id', $input['product_ids'])->delete();

        return deleted();
    }
}
